package projorientado.ocr.vfeature.impl;

import java.util.logging.Level;
import java.util.logging.Logger;
import projorientado.ocr.vfeature.*;
import projorientado.image.ImageLayerData;

/**
 *  Sequencia de features que é mapeado diretamente cada pixel da imagem.
 */
public class ImageLayerFeatures implements SequentialFeatures {

    public static final int
        FORMATATION_RESIZE = 1,
        FORMATATION_ALIGN_TOP_RIGHT = 2,
        FORMATATION_ALIGN_CENTER = 3;
    
    private ImageLayerData image;
    private float xScale = -1,yScale = -1;
    private int centerX,centerY;
    private int width,height,len,formatation;

    public ImageLayerFeatures(ImageLayerData image, int format, int width, int height) {
        this.image = image;
        this.formatation = format;
        if(format == FORMATATION_RESIZE) {
            try {
                xScale = (float)width/image.getWidth();
                yScale = (float)height/image.getHeight();
                float diffScale = Math.abs(xScale - yScale);
                if(diffScale > 0.3f) {
                    float scale = Math.min(xScale, yScale);
                    xScale = scale;
                    yScale = scale;
                    if(xScale > yScale) {
                        xScale += 0.3f;
                    } else {
                        yScale += 0.3f;
                    }
                }
                
                this.image = image.resize((int)(image.getWidth()*xScale), (int)(image.getHeight()*yScale));
                this.image.normalizeThresholding(0);
                formatation = FORMATATION_ALIGN_CENTER;
            } catch (Exception ex) {
                Logger.getLogger(ImageLayerFeatures.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        setSize(width,height);
    }

    public ImageLayerFeatures() {
    }
    
    public ImageLayerData toImageLayerData() {
        ImageLayerData ret = new ImageLayerData(width,height);
        for(int n = 0; n < featuresSize(); n++){ 
            int px = n % width;
            int py = (n-px)/width;
            ret.setPixel(px, py, getFeature(n));
        }
        return ret;
    }
    
    public ImageLayerData getImage() {
        return image;
    }

    public void setImage(ImageLayerData image) {
        this.image = image;
        setSize(width,height);
    }
    
    public void setSize(int width, int height) {
        this.width = width;
        this.height = height;
        this.len = width*height;
        if(image != null) {
            xScale = (float)width/image.getWidth();
            yScale = (float)height/image.getHeight();
            centerX = (image.getWidth() - width)/2;
            centerY = (image.getHeight() - height)/2;
        }
    }
    
    public int featuresSize() {
        return len;
    }

    public float getFeature(int n) {
        if(n < 0)
            return 1f;
        
        int px = n % width;
        int py = (n-px)/width;
        
        if(formatation == FORMATATION_ALIGN_CENTER) {
            px += centerX;
            py += centerY;
        } else if(formatation == FORMATATION_RESIZE) {
            return image.getScaledPoint(px, py, xScale, yScale);
        }
        
        if(between(px,0,image.getWidth()) && between(py,0,image.getHeight())) {
            return image.getPixel(px, py);
        } else
            return 1f;
    }
        
    private static boolean between(int v, int greatOrEqual, int lessThan) {
        return v >= greatOrEqual && v < lessThan;
    }

    public int getHeight() {
        return height;
    }

    public int getWidth() {
        return width;
    }

    public int getFormatation() {
        return formatation;
    }

    public void setFormatation(int formatation) {
        this.formatation = formatation;
    }

}
